package com.zsrt.java.day20161227.lh.homework.demo05;

import java.util.Arrays;

import org.junit.Test;

/**
 * 斗地主  52  10x5   3张底牌
 * 	玩家01	是什么
 * 	玩家02	是什么
 *  ...
 * 	玩家010	是什么
 * 
 * 已知：
 * 	1.10位玩家
 * 	2.共52张牌，每人5张牌，剩2张
 *  3.比大小：
 *  	有牛：其中任意3张牌之和 ，对10求模结果是0为有牛；剩下2张 对10求模结果是几就牛几
 *  	没牛：最大牌的点数
 *  			相同：比较花色，黑桃>红心>梅花>方块
 *  			不同：谁点数大就赢
 * 求：
 * 	1 每人的牌是什么
 *  2谁有牛，牛几；谁没牛，那个牌最大
 *  3谁赢
 * 
 * 分析：
 * 	1 定义数组装好13个点数，
 * 	2 定义数组装好4个花色
 * 	3 把1.2组合上大小王组合成一副牌
 *  4 定义10个玩家数组、定义剩牌
 *  5 随机数确定抽取发给玩家
 *  6 判断玩家是否有牛，牛几；没牛，那个牌最大
 *  7 谁赢
 */
public class DouNiu {
	
	/**
	 * 用于比较花色
	 * @param huase1	花色1
	 * @param huase2	花色2
	 * @return	牌大的花色
	 */
	public static String compareHuase(String huase1,String huase2){
		String result = "";
		int hsNum1 = 0;
		int hsNum2 = 0;
		hsNum1 = fanyiHuase(huase1);
		hsNum2 = fanyiHuase(huase2);
		if(hsNum1 > hsNum2){
			result = huase1;
		}else{
			result = huase2;
		}
		return result;
	}
	
	/**
	 * 用于比较点数
	 * @param point1	点数1
	 * @param point2	点数2
	 * @return	大的点数
	 */
	public static String comparePoint(String point1,String point2){
		String result = "";
		int pNum1 = 0;
		int pNum2 = 0;
		pNum1 = fanyiPoint(point1);
		pNum2 = fanyiPoint(point2);
		if(pNum1 > pNum2){
			result = point1;
		}else{
			result = point2;
		}
		return result;
	}

	/**
	 * 把花色 翻译成 对应大小的数字
	 * @param huase1	花色
	 * @return	
	 */
	public static int fanyiHuase(String huase1) {
		int hsNum1;
		switch (huase1) {
			case "黑桃":	hsNum1 = 4;		break;
			case "红桃":	hsNum1 = 3;		break;
			case "梅花":	hsNum1 = 2;		break;
			default:	hsNum1 = 1;		break;
		}
		return hsNum1;
	}
	
	/**
	 * 把牌 从String 翻译 成 int
	 * @param point1	String类型点数
	 * @return	int类型点数
	 */
	public static int fanyiPoint(String point1) {
		int pNum1 = 0;
		switch (point1) {
			case "K":	pNum1 = 13;		break;
			case "Q":	pNum1 = 12;		break;
			case "J":	pNum1 = 11;		break;
			case "10":	pNum1 = 10;		break;
			case "9":	pNum1 = 9;		break;
			case "8":	pNum1 = 8;		break;
			case "7":	pNum1 = 7;		break;
			case "6":	pNum1 = 6;		break;
			case "5":	pNum1 = 5;		break;
			case "4":	pNum1 = 4;		break;
			case "3":	pNum1 = 3;		break;
			case "2":	pNum1 = 2;		break;
			case "1":	pNum1 = 1;		break;
		}
		return pNum1;
	}

	/**
	 * 判断牛几
	 * @param index1	 3张组合为牛，其中一张的位置
	 * @param index2	 另一张的位置
	 * @param index3	 最后一张的位置
	 * @param peopleNiu	 有牛玩家的牌
	 * @return	牛几
	 */
	public static int judgeNiu(int index1, int index2, int index3, int[] peopleNiu) {
		int niuJi = 0;
		int   sum = 0;
//		System.out.print(index1+":"+index2+":"+index3+"为牛    ");
		for(int i = 0;i<peopleNiu.length;i++){
			if(i!=index1 && i!=index2 && i!=index3){
				sum = sum+peopleNiu[i];
			}
		}
		niuJi = sum%10;
		return niuJi;
	}
	
	/**
	 * --从5个中抽取3个相加：他们的和是否是10的倍数（对10求模等于0）
	 * 012	013		014		023		024		034
	 * 123	124		134		
	 * 234
	 * @param people	玩家
	 * @param pointInt	转换成1~10的数组
	 * 
	 * 判断玩家是否有牛：有牛时，牛几
	 * @param people	玩家数
	 * @param pointInt	玩家的牌的点数的数组
	 * @return	牛几
	 */
	public static int yMeiYouNiu(int people, int[] pointInt){
		int result  = -1;
		int[][]youNiu = {{0,1,2},{0,1,3},{0,1,4},{0,2,3},{0,2,4},{0,3,4},{1,2,3},{1,2,4},{1,3,4},{2,3,4}};
		for(int i = 0;i<youNiu.length;i++){
			int index1 = youNiu[i][0];
			int index2 = youNiu[i][1];
			int index3 = youNiu[i][2];
//			System.out.println(Arrays.toString(youNiu[i]));
			if((pointInt[index1]+pointInt[index2]+pointInt[index3])%10 == 0){
				
				//判断牛几
				result = judgeNiu(index1,index2,index3,pointInt);
				break;
			}
		}
		return result;
	}
	
	/**
	 * 获取点数跟花色都最大的牌
	 * @param point	点数
	 * @param hs	花色
	 * @return	点数跟花色都最大的牌
	 */
	public static String[] makeMax(String[][] point,String[][] hs){
		int people = point.length;
		int pai  = point[0].length;
		
		//建立一个数组保存玩家的最大牌
		String[] maxPai = new String[people];
		for(int i = 0;i<people;i++){
			
			//保存比较后得到的大的花色
			String maxHs = "";
			String maxPoint="";
			int gindex =0;
			for(int j = 0;j<pai;j++){
				String p = point[i][j];
				
				//1.是否已经保存有牌
				if(maxPoint == null){
					
					//1.1没有，直接保存（点数）
					maxPoint = p;
					
					//创建变量gindex：保存maxHs的下标
					gindex = j;
				}else{
					
					//1.2 有，判断点数是否相同
					if(maxPoint.equals(p)){
						
						//2.1如果点数相同，比较花色，保存大花色
						maxHs = compareHuase(hs[i][j], hs[i][gindex]);
					}else{
						
						//2.2点数不同，比较大小
						maxPoint = comparePoint(maxPoint, p);
						
						//判断最大点数是否改变
						//发生改变时，记得把花色下标也改变
						if(maxPoint.equals(p)){
							maxHs = hs[i][j];
							gindex = j;
						}else{
							maxHs = hs[i][gindex];
						}
					}
				}
				if(j==4){
					maxPai[i] = maxHs+maxPoint;
				}
			}
		}
		return maxPai;
	}
	
	/**
	 * 斗牛有木有
	 */
	@Test
	public void douNiu(){
		int zhipaiLength = 52;		//纸牌张数,没大小王
		int pai = 5;			//每人获得纸牌张数
		int people = 10;
		
		//1 定义数组装好13个点数，
		String[] dianshu = new String[13];
		for(int i=1;i<=people;i++){
			dianshu[i-1]=i+"";
		}
		dianshu[10] = "J";
		dianshu[11] = "Q";
		dianshu[12] = "K";
		
		//2 定义数组装好4个花色
		String[] huase = {"黑桃","红桃","梅花","方块"};
		
		//定义纸牌
		String[] zhipai = new String[zhipaiLength];
		
		//纸牌的index
		int index = 0;
		
		//3 把1.2组合成一副牌
		for(int i = 0;i<huase.length;i++){
			for(int j = 0;j<dianshu.length;j++){
				zhipai[index] = huase[i]+dianshu[j];
				index++;
			}
		}
		
		//4 定义10个玩家数组、定义剩牌
		String[][] player = new String[people][pai];
		String[]   last   = new String[2];
		
		int temp = zhipaiLength;
		
		//5 随机数确定抽取纸牌发给玩家
		for(int i = 0;i<pai;i++){
			for(int j = 0;j<people;j++){
				int ran = (int)(Math.random()*temp);
				player[j][i] = zhipai[ran];
				
				//玩家抽取一张牌后，纸牌长度-1，即从牌堆删去这张牌
				temp--;
//				zhipai = FightTheLandlord.delete(zhipai, zhipai[ran]);
			}
		}
		//剩下2张牌
		last = zhipai;
		
		for(int i = 0;i<people;i++){
			System.out.println("玩家"+(i+1)+"的牌是：\t"+Arrays.toString(player[i]));
		}
		System.out.println("剩下的牌：\t"+Arrays.toString(last));
		System.out.println("====================");
		
		//6.1 析出每张纸牌的点数 、花色，并用新数组存放
		String[][] point = new String[people][pai];
		String[][] hs	 = new String[people][pai];
		for(int i = 0;i<people;i++){
			for(int j = 0;j<pai;j++){
				String p = player[i][j];			
				if(p.length() == 3){
					String p1 = ""+p.charAt(2);
					String p2 = ""+p.charAt(0)+p.charAt(1);
					point[i][j] = p1;
					hs[i][j]    = p2;
//					System.out.print(p.charAt(2)+"  ");
				}else{
					String p1 = ""+p.charAt(2)+p.charAt(3);
					String p2 = ""+p.charAt(0)+p.charAt(1);
					point[i][j] = p1;
					hs[i][j]    = p2;
//					System.out.print(""+p.charAt(2)+p.charAt(3)+"  ");
				}
			}
//			System.out.println();
		}

		//把点数 数组 转换成1到10的数字
		int[][] pointInt = new int[people][pai];
		for(int i = 0 ;i < people; i++){
			for(int j = 0; j < pai; j++){
				int ptemp = fanyiPoint(point[i][j]);
				if(ptemp >= 10){
					pointInt[i][j] = 10;
				}else{
					pointInt[i][j] = ptemp;
				}
			}
		}
		
		//所有玩家的最大的牌
		String[] maxPai = makeMax(point, hs);
		
		//6.2  判断是否有牛，牛几;没牛时，找出最大的牌 
		int[] judge= new int[people];
		for(int i = 0 ;i<people;i++){
			judge[i] = yMeiYouNiu(people, pointInt[i]);
			if(judge[i] != -1){
				
				//6.2.1 有牛，牛几  (有牛返回：牛几)
				if(judge[i] == 0){
					System.out.println("玩家"+(i+1)+"有牛：牛牛");
				}else{
					System.out.println("玩家"+(i+1)+"有牛：牛"+judge[i]);
				}
			}else{
				
				//6.2.2  没牛：返回最大牌
				//玩家的最大牌
				String maxOne = maxPai[i];
				System.out.println("玩家"+(i+1)+"没牛：最大牌是："+maxOne);
			}
		}
		
		System.out.println("======================");
		//谁赢了
		//创建临时数组temp02
		int[]temp02 = new int[people];
		int winner01 = 0;
		for(int i =0;i<people;i++){
			if(judge[i] == 0){
				judge[i] = 10;
			}
			temp02[i] = judge[i];
		}
		String winners = "";
		
		//冒泡排序:取出最大值
		for(int i = 0;i < people; i++){
			for(int j = 1;j < people-i; j++){
				
				//前一个  跟  后一个比较：01 12 23
				if(temp02[j-1] > temp02[j]){
					int   tt   = temp02[j-1];
					temp02[j-1] = temp02[j];
					temp02[j]   = tt;
				}
			}
		}
		
		int judgeMax = temp02[people-1];
		
		//遍历所有玩家的judge看谁的点数大
		for(int i = 0;i<people;i++){
			if(judge[i] == judgeMax){
				winner01 = i+1;
//				System.out.println("点数最大的玩家：有玩家："+winner01);
				winners = winners+winner01;
			}
		}
		System.out.println("点数最大的玩家："+winners);
		
		//6.3 获取点数最大 且 相同 的玩家的最大的牌
		//点数最大的玩家有多少个：winLen
		int winLen = winners.length();
		
		//6.3.1点数最大的玩家的最大的牌集合：String[] winPais
		String[] winPais = new String[winLen];
		
		//6.3.2点数最大的玩家的集合：winNum
		int[] winNum = new int[winLen];
		for(int i = 0;i<winners.length();i++){
			winNum[i] = Integer.parseInt(winners.charAt(i)+"");
		}
		for(int i = 0 ;i<winLen;i++){
			winPais[i] = maxPai[winNum[i]-1];
		}
		System.out.println("点数最大的玩家：的最大的牌是："+Arrays.toString(winPais));
		
		/**
		 * --斗牛的点数最大的玩家的集合（点数相同），比较最大的那张牌
		 * 先比较点数
		 * 	   点数相同：比较花色
		 *   点数不同：输出点数大的
		 */
		//6.3.3 新建保存  玩家的点数和花色的数组winHS、winPoint
		String[] winsPoint = new String[winLen];
		String[] winsHS = new String[winLen];
		for(int i =0;i<winLen;i++){
			
			//析出点数跟花色
			String winp = winPais[i];
			if(winp.length() == 3){
				String p1 = ""+winp.charAt(2);
				String p2 = ""+winp.charAt(0)+winp.charAt(1);
				winsPoint[i] 	= p1;
				winsHS[i] = p2;
			}else{
				String p1 = ""+winp.charAt(2)+winp.charAt(3);
				String p2 = ""+winp.charAt(0)+winp.charAt(1);
				winsPoint[i] 	= p1;
				winsHS[i] = p2;
			}
		}
		
		//6.3.4找出最大那张牌的点数：tempStr
		String whichHS = winsHS[0];
		for(int i = 0;i<winLen;i++){
			whichHS = comparePoint(whichHS, winsHS[i]);
		}
		
		//6.3.5找出 有那张点数最大的牌的玩家的数量：winSum;
		int winSum = 0;
		for(int i = 0;i<winLen;i++){
			
			//  点数最大的玩家 数量 ：winSum
			if(winsHS[i].equals(whichHS)){
				winSum++;
			}
		}
		
		//定义 花色数组：如两个牛牛的玩家，最大牌都是K：保存到winOneHS
		String[] winOnePoint = new String[winSum];
		
		int winOneHSIndex =0;
		for(int i = 0;i<winLen;i++){
			
			if(winsHS[i].equals(whichHS)){
				//winOneHS.length =winSum   ;    winHS.length =winLen
				//如何把       winOneHS[i] = winHS[i];
				 winOnePoint[winOneHSIndex] = winsPoint[i];
				 winOneHSIndex++;
			}
		}
//		System.out.println(Arrays.toString(winOnePoint)+"--点数max");
		
		//找到了最大的点数，比较花色:whichHS
		String whichPoint = winOnePoint[0];
		for(int i = 0;i<winSum;i++){
			whichPoint = compareHuase(whichPoint, winOnePoint[i]);
		}
		
//		System.out.println(whichPoint);
//		System.out.println(whichHS);
		String winnerMaxPai = whichHS+whichPoint;
		
		
		int winIndex = 0;
		//从所有玩家最大牌的数组，搜索点数最大花色最大的牌对应的玩家
		for(int i = 0;i<people;i++){
			if(winnerMaxPai.equals(maxPai[i])){
				winIndex = i+1;
				break;
			}
		}
		System.out.println("玩家"+winIndex+"：赢了");
//		String winPlayer = comparePoint(point1, point2);
	}

}
